﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace bytes与struct的序列化
{
    public class CSerialization
    {
        /// <summary>
        /// 结构体转byte数组
        /// </summary>
        /// <param name="structObj">要转换的结构体</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] StructToBytes(object structObj)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(structObj);
            //创建byte数组
            byte[] bytes = new byte[size];
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将结构体拷到分配好的内存空间
            Marshal.StructureToPtr(structObj, structPtr, false);
            //从内存空间拷到byte数组
            Marshal.Copy(structPtr, bytes, 0, size);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回byte数组
            return bytes;
        }

        /// <summary>
        /// byte数组转结构体
        /// </summary>
        /// <param name="bytes">byte数组</param>
        /// <param name="type">结构体类型</param>
        /// <returns>转换后的结构体</returns>
        public static object BytesToStuct(byte[] bytes, Type type)
        {
            //得到结构体的大小
            int size = Marshal.SizeOf(type);
            //byte数组长度小于结构体的大小
            if (size > bytes.Length)
            {
                //返回空
                return null;
            }
            //分配结构体大小的内存空间
            IntPtr structPtr = Marshal.AllocHGlobal(size);
            //将byte数组拷到分配好的内存空间
            Marshal.Copy(bytes, 0, structPtr, size);
            //将内存空间转换为目标结构体
            object obj = Marshal.PtrToStructure(structPtr, type);
            //释放内存空间
            Marshal.FreeHGlobal(structPtr);
            //返回结构体
            return obj;
        }

        /// <summary>
        /// 大端转小端
        /// </summary>
        /// <param name="data"></param>
        /// <returns>返回小端数据</returns>
        public static UInt16 BigendToSmallend(UInt16 data)
        {
            string s = null;
            if(BitConverter.IsLittleEndian == true)//处于小端模式
            {
                s = data.ToString();
            }
            else
            {
                byte[] bData = BitConverter.GetBytes(data);
                Array.Reverse(bData);
                s = BitConverter.ToString(bData);
            }
            return Convert.ToUInt16(s); ;
        }

        /// <summary>
        /// 小端转大端
        /// </summary>
        /// <param name="data"></param>
        /// <returns>返回大端数据</returns>
        public static UInt16 SmallendToBigend(UInt16 data)
        {
            string s = null;
            
            if(BitConverter.IsLittleEndian == true)//处于小端模式
            {
                byte[] bData = BitConverter.GetBytes(data);
                Array.Reverse(bData);
                s = BitConverter.ToString(bData);
            }
            else
            {
                s = data.ToString();
            }
            return Convert.ToUInt16(s);
        }

        public static string ByteCodeOrderConversionToString(byte[] bData)
        {
            string s = null;
            //Array.Reverse(bData);
            s = BitConverter.ToString(bData);
            s = s.Replace("-", "");
            return s;
        }

        /// <summary>
        /// 字节码顺序转换
        /// </summary>
        /// <param name="data">需要转换的数据</param>
        /// <returns>返回转换的数据</returns>
        public static UInt16 ByteCodeOrderConversion(UInt16 data)
        {
            byte[] bData = BitConverter.GetBytes(data);
            string s = ByteCodeOrderConversionToString(bData);
            return Convert.ToUInt16(s,16);
        }

        /// <summary>
        /// 字节码顺序转换
        /// </summary>
        /// <param name="data">需要转换的数据</param>
        /// <returns>返回转换的数据</returns>
        public static UInt32 ByteCodeOrderConversion(UInt32 data)
        {
            byte[] bData = BitConverter.GetBytes(data);
            string s = ByteCodeOrderConversionToString(bData);
            return Convert.ToUInt32(s,16);
        }

        /// <summary>
        /// 字节码顺序转换
        /// </summary>
        /// <param name="data">需要转换的数据</param>
        /// <returns>返回转换的数据</returns>
        public static UInt64 ByteCodeOrderConversion(UInt64 data)
        {
            byte[] bData = BitConverter.GetBytes(data);
            string s = ByteCodeOrderConversionToString(bData);
            return Convert.ToUInt64(s,16);
        }

    }
}
